package com.thinkgsp.jxc.service.impl;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.thinkgsp.jxc.model.BillDetail;
import com.thinkgsp.jxc.model.CheckBill;
import com.thinkgsp.jxc.model.CheckBillDetail;
import com.thinkgsp.jxc.model.CheckResult;
import com.thinkgsp.jxc.model.OtherStockOutBill;
import com.thinkgsp.jxc.persistence.CheckBillMapper;
import com.thinkgsp.jxc.persistence.mybatis.PagingResult;
import com.thinkgsp.jxc.service.BillService;
import com.thinkgsp.jxc.service.CheckBillService;
import com.thinkgsp.jxc.service.ServiceException;

@Service("checkBillService")
@Transactional
public class CheckBillServiceImpl extends GeneralServiceImpl implements CheckBillService {

	@Autowired
	private CheckBillMapper checkBillMapper;
	@Autowired
	private BillService billService;
	

	public CheckBill getCheckBill(Long billId) {
		return checkBillMapper.getBillById(billId);
	}

	public List<CheckBillDetail> getCheckBillDetail(Long billId) {
		return checkBillMapper.getCheckBillDetail(billId);
	}

	public List<CheckBill> findCheckBill(Date begDate, Date endDate,
			Integer deptId) {
		return checkBillMapper.getBillList(begDate, endDate, deptId);
	}

	public PagingResult<CheckBill> findCheckBill(Date begDate, Date endDate,
			Integer deptId, int start, int size) {
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put("begDate", begDate);
		params.put("endDate", endDate);
		params.put("deptId", deptId);

		RowBounds rows = new RowBounds(start, size);
		return queryPagingHandler.queryPagingResult(
				"com.thinkgsp.jxc.persistence.CheckBillMapper.getBillListCount", 
				"com.thinkgsp.jxc.persistence.CheckBillMapper.getBillListPaging", params, rows);
	}

	public void saveCheckBill(CheckBill bill) throws ServiceException {
		if(bill == null ) {
			throw new ServiceException("盘点单据对象无效.");
		}
		if(bill.getBillId() == null || bill.getBillId() == 0L) {
			checkBillMapper.insertCheckBill(bill);
		} else {
			checkBillMapper.updateCheckBill(bill);
		}
	}

	public void archiveCheckBill(long billId) throws ServiceException {
		buildLossBill(billId);
	}

	public void unArchiveCheckBill(long billId) throws ServiceException {
		CheckBill bill = checkBillMapper.getBillById(billId);
		if(!bill.getArchived()) {
			throw new ServiceException("单据未归档，不允许反归档。");
		}
		Long stockBillId = bill.getJxcBillId();
		billService.unArchiveBill(stockBillId);
		billService.deleteBill(stockBillId);
		checkBillMapper.deleteJxcBill(billId);
		bill.setJxcBillId(null);
		bill.setArchived(false);
	}

	public void deleteCheckBill(long billId) throws ServiceException {
		CheckBill bill = checkBillMapper.getBillById(billId);
		if(bill == null) {
			throw new ServiceException("盘点单据ID无效;id=" + billId);
		}
		if(bill.getArchived()) {
			throw new ServiceException("单据已经归档，不允许删除。");
		}
		checkBillMapper.deleteBillDetailByBillId(billId);
		checkBillMapper.deleteCheckBill(billId);
	}

	public void inputCheckBillDetail(CheckBillDetail detail)
			throws ServiceException {
		if(detail.getBillId() == null || detail.getBillId() == 0L) {
			throw new ServiceException("盘点明细无效。");
		}
		if(detail.getProductId()== null || detail.getProductId() == 0) {
			throw new ServiceException("产品ID无效。");
		}
		if(detail.getBatchNoId() == null || detail.getBatchNoId() == 0L) {
			throw new ServiceException("产品批号无效。");
		}
		if(detail.getCheckQty().compareTo(BigDecimal.ZERO) == 0) {
			throw new ServiceException("盘点数量无效。");
		}
		checkBillMapper.insertBillDetail(detail);
	}

	public void deleteCheckBillDetail(long id) throws ServiceException {
		checkBillMapper.deleteBillDetail(id);
	}

	public List<CheckResult> testCalc(Long billId) throws ServiceException {
		if(billId == null || billId == 0L) {
			throw new ServiceException("单据ID无效。");
		}
		return checkBillMapper.testCalc(billId);
	}

	public List<CheckResult> findOmitedInventory(Long billId) {
		return checkBillMapper.findOmited(billId);
	}

	public void buildLossBill(Long billId) throws ServiceException {
		CheckBill bill = checkBillMapper.getBillById(billId);
		if(bill == null || bill.getBillId() == null || bill.getBillId() == 0L) {
			throw new ServiceException("盘点单据无效。");
		}
		if(bill.getArchived()) {
			throw new ServiceException("单据已经归档。");
		}
		List<CheckResult> results = checkBillMapper.testCalc(billId);
		if(results == null || results.size() == 0) {
			throw new ServiceException("未检索到盘点记录。");
		}
		OtherStockOutBill stockBill = new OtherStockOutBill("盘损单");
		stockBill.setRemark("盘点单据【" + billId + "】对应的盘损单");
		for(CheckResult result : results) {
			if(result.getCurrentQty().compareTo(result.getCheckQty()) != 0) {
				BillDetail detail = stockBill.createDetail();
				detail.setProductId(result.getProductId());
				detail.setProduct(result.getProduct());
				detail.setInvAddId(bill.getInvAddId());
				detail.setInvAdd(bill.getInvAdd());
				detail.setBatchNoId(result.getBatchNoId());
				detail.setBatchNo(result.getBatchNo());
				detail.setQuantity(result.getLossQty());
				detail.setPrice(detail.getCostPrice());
				stockBill.getDetails().add(detail);
			}
		}
		billService.saveBill(stockBill);
		billService.archiveBill(stockBill);
		checkBillMapper.updateJxcBill(billId, stockBill.getBillId());
		bill.setJxcBillId(stockBill.getBillId());
		bill.setArchived(true);
	}

}
